#ifndef __QUEUE_H__
#define __QUEUE_H__
/*-----------------------------* 
 *  Macros for others          * 
 *----------------------------*/ 
# define START_DEFINE_QUEUE(__NAME,__SIZE,__TYPE,__POS_TYPE)\
                __TYPE  s_Queue##__NAME##Buffer[(__SIZE)];\
                __POS_TYPE  s_Queue##__NAME##Tail = 0;\
                __POS_TYPE  s_Queue##__NAME##Head = 0;\
                __POS_TYPE  s_Queue##__NAME##Counter = 0;\
                \
                uint8_t Queue_##__NAME##_Add_Data(__TYPE Data)\
                {\
                    SAFE_ATOM_CODE\
                    (\
                        if ((s_Queue##__NAME##Tail == s_Queue##__NAME##Head)\
                          && (s_Queue##__NAME##Counter != 0))\
                        {\
                            EXIT_SAFE_ATOM_CODE();\
                            return FALSE;\
                        }\
                        \
                        s_Queue##__NAME##Buffer[s_Queue##__NAME##Head] = Data;\
                        s_Queue##__NAME##Head = (s_Queue##__NAME##Head == (__SIZE - 1)) ? \
                                                0 : (s_Queue##__NAME##Head + 1);\
                        s_Queue##__NAME##Counter++;\
                    )\
                    \
                    return TRUE;\
                }\
                \
                uint8_t Queue_##__NAME##_Get_Data(__TYPE *pData)\
                {\
                    SAFE_ATOM_CODE\
                    (\
                        if (((s_Queue##__NAME##Tail == s_Queue##__NAME##Head)\
                          && (s_Queue##__NAME##Counter == 0))\
                          || (pData == NULL))\
                        {\
                            EXIT_SAFE_ATOM_CODE();\
                            return FALSE;\
                        }\
                        \
                        (*pData) = s_Queue##__NAME##Buffer[s_Queue##__NAME##Tail];\
                        s_Queue##__NAME##Tail = (s_Queue##__NAME##Tail == (__SIZE - 1)) ? \
                                                0 : (s_Queue##__NAME##Tail + 1);\
                        s_Queue##__NAME##Counter--;\
                    )\
                    \
                    return TRUE;\
                }\
                \
                uint8_t Queue_##__NAME##_Check_Empty(void)\
                {\
                    SAFE_ATOM_CODE\
                    (\
                        if ((s_Queue##__NAME##Tail == s_Queue##__NAME##Head)\
                          && (s_Queue##__NAME##Counter == 0))\
                        {\
                            EXIT_SAFE_ATOM_CODE();\
                            return TRUE;\
                        }\
                    )\
                    return FALSE;\
                }\
                \
                __POS_TYPE Queue_##__NAME##_Get_Count(void)\
                {\
                    return s_Queue##__NAME##Counter;\
                }
                 
                 
                 
# define END_DEFINE_QUEUE 

# define GET_QUEUE_DATA(__NAME,__ADDR)          Queue_##__NAME##_Get_Data(__ADDR) 
# define ADD_QUEUE_DATA(__NAME,__VAR)           Queue_##__NAME##_Add_Data(__VAR) 
# define GET_QUEUE_COUNT(__NAME)                Queue_##__NAME##_Get_Count() 
# define CHECK_QUEUE_EMPTY(__NAME)              Queue_##__NAME##_Check_Empty() 

# define FN_GET_QUEUE_DATA(__NAME)              Queue_##__NAME##_Get_Data 

# define FN_ADD_QUEUE_DATA(__NAME)              Queue_##__NAME##_Add_Data 
# define FN_GET_QUEUE_COUNT(__NAME)             Queue_##__NAME##_Get_Count 
# define FN_CHECK_QUEUE_EMPTY(__NAME)           Queue_##__NAME##_Check_Empty 


# define EXTERN_REFERENCE_QUEUE(__NAME,__TYPE,__POS_TYPE)  \
            extern uint8_t Queue_##__NAME##_Add_Data(__TYPE Data);\
            extern uint8_t Queue_##__NAME##_Get_Data(__TYPE *pData);\
            extern uint8_t Queue_##__NAME##_Check_Empty(void);\
            extern __POS_TYPE Queue_##__NAME##_Get_Count(void);
             
/*-----------------------------* 
 *  type definitions           * 
 *----------------------------*/ 


#endif
